"use strict";
const moment = require("moment");
const { Model } = require("sequelize");
const { isPwd } = require("../utils/is");
const { cryptoEncode } = require("../utils/crypto");
const { Conflict, BadRequest } = require("http-errors");

module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    // 关联模型
    static associate(models) {
      models.User.belongsToMany(models.Role, {
        through: models.UsersRoles,
        foreignKey: "userId",
        as: "roles",
      });
    }
  }
  User.init(
    {
      username: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: { msg: "用户名必须填写。" },
          notEmpty: { msg: "用户名不能为空。" },
          len: { args: [2, 45], msg: "用户名长度必须是2 ~ 45之间。" },
          async isUnique(value) {
            const user = await User.findOne({ where: { username: value } });
            if (user) {
              throw new Conflict("用户名已经存在。请直接登陆");
            }
          },
        },
      },
      fullName: DataTypes.STRING,
      password: {
        type: DataTypes.STRING,
        allowNull: false,
        set(value) {
          if (!value) throw new BadRequest("密码必须填写。");
          if (!isPwd(value)) {
            throw new BadRequest(
              "密码应包含字母、数字、特殊字符八位或八位以上的数字"
            );
          }
          this.setDataValue("password", cryptoEncode(value));
        },
      },
      phone: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notNull: { msg: "手机号必须填写。" },
          notEmpty: { msg: "手机号不能为空。" },
          async isUnique(value) {
            const user = await User.findOne({ where: { phone: value } });
            if (user) {
              throw new Conflict("手机号已存在，请直接登录。");
            }
          },
        },
      },
      email: {
        type: DataTypes.STRING,
        validate: {
          isEmail: { msg: "邮箱格式不正确。" },
          async isUnique(value) {
            const user = await User.findOne({ where: { email: value } });
            if (user) {
              throw new Conflict("邮箱已存在，请直接登录。");
            }
          },
        },
      },
      avatar: {
        type: DataTypes.STRING,
        validate: {
          isUrl: { msg: "图片地址不正确。" },
        },
      },
      gender: {
        type: DataTypes.TINYINT,
        validate: {
          isIn: {
            args: [[3, 1, 2]],
            msg: "性别的值必须是，男性：1 女性：2 未选择：3。",
          },
        },
      },
      status: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        validate: {
          notNull: { msg: "状态必须填写。" },
          notEmpty: { msg: "状态不能为空。" },
        },
      },
      isDelete: DataTypes.BOOLEAN,
      createdAt: {
        type: DataTypes.DATE,
        get() {
          return moment(this.getDataValue("createdAt")).format(
            "YYYY-MM-DD HH:mm:ss"
          );
        },
      },
      updatedAt: {
        type: DataTypes.DATE,
        get() {
          return moment(this.getDataValue("updatedAt")).format(
            "YYYY-MM-DD HH:mm:ss"
          );
        },
      },
    },
    {
      sequelize,
      modelName: "User",
    }
  );
  return User;
};
